#include "logic.h"
#include "../../log.h"
#include <mutex>

Logic::Logic():m_is_stop(false)
{
    RegisterFunc();
    m_work_thread = std::thread(&Logic::Work, this);
}

void Logic::Work()
{
    while(true)
    {
        std::unique_lock<std::mutex> lock(m_queue_mutex);

        // while(m_msg_que.empty() && !m_is_stop)
        // {
        //     m_cv.wait(lock);
        // }
        m_cv.wait(lock, [this](){
            return !m_msg_que.empty() || m_is_stop;
        });

        while(!m_msg_que.empty())
        {
            auto msg_node = m_msg_que.front();
            auto find = m_func_map.find(msg_node->m_recv_node->GetMsgId());
            if(find != m_func_map.end())
            {
                find->second(msg_node->m_session, msg_node->m_recv_node->GetMsgId(), 
                    std::string(msg_node->m_recv_node->m_data.get(), msg_node->m_recv_node->m_total_len));
            }
            m_msg_que.pop();
        }

        if(m_is_stop)
        {
            break;
        }
    }
}

void Logic::AddMagQueue(std::shared_ptr<LogicNode> node)
{
    std::lock_guard<std::mutex> lock(m_queue_mutex);
    m_msg_que.push(node);
    m_cv.notify_one();
}

void Logic::RegisterFunc()
{
    m_func_map[MSG_HELLO_WORLD] = [this](std::shared_ptr<Session> session, const uint32_t& msg_id, const std::string& msg_data){
        HelloWorldCallBack(session, msg_id, msg_data);
    };
}


void Logic::HelloWorldCallBack(std::shared_ptr<Session> session, const uint32_t& msg_id, const std::string& msg_data)
{
    log_info("msg id:{}, msg data:{}", msg_id, msg_data);
    std::string msg = "hello world";
    log_debug("msg:{}, msg len:{}", msg, msg.length());
    session->Send(msg.c_str(), msg.length(), MSG_HELLO_WORLD);
}

Logic::~Logic()
{
    m_is_stop = true;
    m_cv.notify_one();
    if(m_work_thread.joinable())
    {
        m_work_thread.join();
    }
}